/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-05
 * V4.0
 */
package com.jphenix.service.nodeloader.instancea;

import com.jphenix.driver.nodehandler.instancea.NodeHandler;
import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.share.tools.StaticHtml;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.viewhandler.INodeHandler;
import com.jphenix.standard.viewhandler.INodeModel;
import com.jphenix.standard.viewhandler.IViewHandler;

import java.util.ArrayList;
import java.util.List;

/**
 * 按照HTML模板操作指定HTML处理类
 * 
 * 指定的HTML中没有标记位置的属性信息
 * 程序通过模板中标记位置的属性信息操作对应的HMTL文件
 * 
 * com.jphenix.service.nodeloader.instancea.NodeModelHandler
 * 
 * @author 刘虻
 * 2008-12-10下午06:22:52
 */
@ClassInfo({"2014-06-05 16:19","按照HTML模板操作指定HTML处理类"})
public class NodeModelHandler extends ABase implements INodeModel {

	/**
	 * 构造函数
	 * 2008-12-10下午06:22:52
	 */
	public NodeModelHandler() {
		super();
	}
	
	/**
	 * 通过模板获取指定位置的节点序列
	 * 
	 * 目标对象从模板页面对象中获取信息
	 * <!TARGET URL="" />
	 * 
	 * @author 刘虻
	 * 2008-12-10下午07:05:43
	 * @param mVdh 模板HTML对象
	 * @param mCVdh 模板指定位置的循环元素
	 * @param isVirtual 指定循环元素是否为虚拟元素(目标HTML中不存在的元素)
	 * @return 指定位置的节点序列
	 * @throws Exception 执行发生异常
	 */
	@Override
    public List<IViewHandler> getTargetViewDataHandlerList(
			IViewHandler mVdh
			,IViewHandler mCVdh
			,boolean isVirtual) throws Exception {
		return getTargetViewDataHandlerList(
				mVdh,mCVdh,getObjectVdh(mVdh),isVirtual);
	}
	
	/**
	 * 通过模板中的目标页面路径信息获取目标HMTL对象
	 * 
	 * <!--* target="" encoding="" -->
	 * 
	 * @author 刘虻
	 * 2008-12-11上午11:47:52
	 * @param mVdh 模板对象
	 * @return 目标对象
	 * @throws Exception 执行发生异常
	 */
	protected IViewHandler getObjectVdh(IViewHandler mVdh) throws Exception {
		//获取目标HTML对象路径
		String urlInfo = mVdh.getParameter("target");
		if (urlInfo.length()<1) {
			return null;
		}
		//页面编码
		String encoding = mVdh.getParameter("encoding");
		if(encoding.length()<1) {
			encoding = mVdh.getDealEncode();
		}
		//构建目标html对象
		IViewHandler oVdh = mVdh.newInstance(true);
		if (!(oVdh instanceof INodeHandler)) {
			throw new Exception("The HTML Model Object Not IHtmlNode");
		}
		//设置目标对象
		((INodeHandler)oVdh).setNodeBody(
				StaticHtml.getUrlString(urlInfo,encoding,log));
		return oVdh;
	}
	
	/**
	 * 通过模板获取指定位置的节点序列
	 * @author 刘虻
	 * 2008-12-10下午07:05:43
	 * @param mVdh 模板HTML对象
	 * @param mCVdh 模板指定位置的循环元素
	 * @param oVdh 目标HTML对象
	 * @param isVirtual 指定循环元素是否为虚拟元素(目标HTML中不存在的元素)
	 * @return 指定位置的节点序列
	 * @throws Exception 执行发生异常
	 */
	protected List<IViewHandler> getTargetViewDataHandlerList(
			IViewHandler mVdh
			,IViewHandler mCVdh
			,IViewHandler oVdh
			,boolean isVirtual) throws Exception  {
		//获取数据表块
		oVdh = 
			getTargetViewDataHandler(mVdh,mCVdh.getParentNode(),oVdh);
		if (oVdh==null) {
			return new ArrayList<IViewHandler>();
		}
		//构建返回值
		ArrayList<IViewHandler> reList = new ArrayList<IViewHandler>();
		if (isVirtual) {
			//节点名序列
			ArrayList<String> nodeNameList = new ArrayList<String>();
			List<IViewHandler> oList = mCVdh.getChildDealNodes(); //获取模板子节点序列
			for (IViewHandler ele:oList) {
				if (ele==null) {
					continue;
				}
				nodeNameList.add(ele.getNodeName());
			}
			if (nodeNameList.size()>0) {
				//获取目标类子节点
				oList = oVdh.getChildDealNodes();
				//构建节点模板
				IViewHandler oMVdh = 
					(IViewHandler)mCVdh.clone();
				oMVdh.removeChildNodes(); //移除虚拟元素中的子节点
				int nodeNamePoint = 0; //节点名指针
				ArrayList<IViewHandler> cNodeList = new ArrayList<IViewHandler>(); //子节点序列
				for(IViewHandler ele:oList) {
					if (ele==null) {
						continue;
					}
					if (ele.getNodeName().equals(nodeNameList.get(nodeNamePoint))) {
						nodeNamePoint++;
						if (nodeNameList.size()<nodeNamePoint) {
							cNodeList.add(ele);
							continue;
						}else {
							cNodeList.add(ele);
							
							nodeNamePoint = 0;
							//构造新的子节点
							IViewHandler oEle = (IViewHandler)oMVdh.clone();
							oEle.addChildNode(cNodeList);
							reList.add(oEle);
							cNodeList = new ArrayList<IViewHandler>();
						}
					}else {
						nodeNamePoint = 0;
					}
				}
			}
		}else {
			//获取节点名
			String nodeName = mCVdh.getNodeName();
			//获取子节点序列
			List<IViewHandler> oList = oVdh.getChildDealNodes();
			for(IViewHandler ele:oList) {
				if (ele==null || !ele.getNodeName().equals(nodeName)) {
					continue;
				}
				reList.add(ele);
			}
		}
		return reList;
	}
	
	/**
	 * 通过指定模板区域获取目标HTML对象中的区域(递归)
	 * @author 刘虻
	 * 2008-12-10下午06:25:56
	 * @param mVdh 模板HTML对象
	 * @param mCVdh 指定模板区域块对象
	 * @return 指定的目标区域块
	 * @throws Exception 执行发生异常
	 */
	@Override
    public IViewHandler getTargetViewDataHandler(
			IViewHandler mVdh,
			IViewHandler mCVdh) throws Exception {
		return getTargetViewDataHandler(mVdh,mCVdh,getObjectVdh(mVdh));
	}
	
	
	/**
	 * 获取新的HTML处理类
	 * @author 刘虻
	 * 2008-12-11上午11:54:19
	 * @return 新的HTML处理类
	 */
	protected INodeHandler getNewHtmlNode() {
		//构造模版解析类
		INodeHandler dh = new NodeHandler();
		dh.setWarning(false);
		return dh;
	}
	
	/**
	 * 获取指定HTML处理类
	 * @author 刘虻
	 * 2008-12-11上午11:53:36
	 * @param filePath HTML文件绝对路径
	 * @param encoding 编码
	 * @return 指定HTML处理类
	 * @throws Exception 执行发生异常
	 */
	@Override
    public INodeHandler getHtmlNode(
			String filePath,String encoding) throws Exception {
		//构造模版解析类
		INodeHandler dh = getNewHtmlNode();
		dh.setDealEncode(encoding);
		dh.setFilePath(filePath);
		return dh;
	}
	
	/**
	 * 通过指定模板区域获取目标HTML对象中的区域(递归)
	 * @author 刘虻
	 * 2008-12-10下午06:25:56
	 * @param mVdh 模板HTML对象
	 * @param mCVdh 指定模板区域块对象
	 * @param oVdh 目标HTML对象
	 * @return 指定的目标区域块
	 * @throws Exception 执行发生异常
	 */
	protected IViewHandler getTargetViewDataHandler(
			IViewHandler mVdh
			,IViewHandler mCVdh
			,IViewHandler oVdh) throws Exception {
		//节点名
		String nodeName = mCVdh.getNodeName();
		if (nodeName.length()<1) {
			return null;
		}
		//获取父节点
		IViewHandler pNode = mCVdh.getParentNode();
		if ((mVdh==null && !pNode.isTopNode()) 
				|| (mVdh!=null && !mVdh.equals(pNode))) {
			oVdh = getTargetViewDataHandler(mVdh,pNode,oVdh);
		}
		if (oVdh==null) {
			return null;
		}
		//获取当前子类的同级子类序列
		List<IViewHandler> cList = pNode.getChildDealNodes();
		int point = -1; //当前子类在同级子类中的位置
		for(IViewHandler ele:cList) {
			if (ele==null || !ele.getNodeName().equals(nodeName)) {
				continue;
			}
			point++;
			if (ele.equals(mCVdh)) {
				break;
			}
		}
		if (point<0) {
			return null;
		}
		//目标对象子类元素序列
		List<IViewHandler> oList = oVdh.getChildDealNodes();
		int oPoint = -1; //目标指定子类指针
		for(IViewHandler ele:oList) {
			if (ele==null || !ele.getNodeName().equals(nodeName)) {
				continue;
			}
			oPoint++;
			if (oPoint==point) {
				return ele;
			}
		}
		return null;
	}
}
